//demo15.cpp ,演示信号量给共享内存加锁

#include "public13.h"

struct People
{
    int age;
    char name[5];
};

int main(int argc, char *argv[])
{
    if(argc!= 3) { cout << "Using: ./demo age name " << endl; return -1; }


    //第1步: 创建/获取共享内存，键值key为0x5005, 也可以使用其他的值
    int shmid = shmget(0x5005, sizeof(People), 0640|IPC_CREAT);
    if(shmid == -1)
    {
        cout << " shmget(0x5005) failed. " << endl; return -1;
    }

    cout << "shmid = " << shmid << endl;

                                                                                      
    //第2步: 把共享内存连接到当前进程的地址空间
    People *ptr = (People *)shmat(shmid, 0, 0);
    if(ptr == (void *)-1)
    {
        cout << "shmat() failed. " << endl;
        return -1;
    }

    //创建并初始化二元信号量(即用于互斥锁的信号量)
    csemp mutex;
    if(mutex.init(0x5005) == false)
    {
        cout << "mutex.init(0x5005) failed. " << endl;
        return -1;
    }

    cout << "申请加锁... " << endl;
    mutex.wait();
    cout << "申请加锁成功. " << endl;


    //第3步: 使用共享内存，对共享内存进行读写
    cout << "原值: age = " << ptr->age << ",  name = " << ptr->name << endl;
    ptr->age = atoi(argv[1]);
    strcpy(ptr->name, argv[2]);
    cout << "新值: age = " << ptr->age << ",  name = " << ptr->name << endl;
    sleep(10);          //模仿操作内存所需时间


    mutex.post();               //解锁
    cout << "解锁。" << endl;



    //第4步: 把共享内存从当前进程中分离
    shmdt(ptr);

    //第5步: 删除共享内存
    if(shmctl(shmid, IPC_RMID, 0) == -1)
    {
        cout << "shmctl failed." << endl;
        return -1;
    }


    return 0;
}
